#pragma once
#include <iostream>
#include <stdarg.h>
#include <fstream>
#include<sys/types.h>
#include<unistd.h>
#include "LockGuard.hpp"
const static char *logname = "log.txt";//日志文件
bool g_save = false; 
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
enum level//日志的等级
{
    DEBUG = 0,
    INFO,
    WARNING,
    ERROR,
    FATAL
};
void save_file(const std::string &logname, std::string &massage)//保存日志到文件中
{
    std::ofstream infile("logname", std::ios::app);
    if (!infile.is_open())
    {
        return;
    }
    infile << massage << std::endl;
    infile.close();
}
// 获取日志等级
std::string get_level_string(int level)
{
    switch (level)
    {
    case DEBUG:
        return "DEBUG";
    case INFO:
        return "INFO";
    case WARNING:
        return "WARNING";
    case ERROR:
        return "ERROR";
    case FATAL:
        return "FATAL";
    default:
        return "None";
    }
}
// 获取时间字符串
std::string get_time_string()
{
    time_t cur_time = time(nullptr);
    if (cur_time == (time_t)-1)
    {
        printf("Failed to get the current time.\n");
        return "None";
    }
    struct tm *formate_time = localtime(&cur_time);
    if (formate_time == nullptr)
    {
        return "None";
    }
    char buffer[1024];
    snprintf(buffer, sizeof(buffer), "%d-%d-%d %d:%d:%d",
             formate_time->tm_year + 1900,
             formate_time->tm_mon + 1,
             formate_time->tm_mday,
             formate_time->tm_hour,
             formate_time->tm_min,
             formate_time->tm_sec);
    return buffer;
}
// 日志信息
void  Log_inf(std::string filename, int line, bool is_save, int level, const char *format, ...)
{
    std::string levelstr = get_level_string(level);
    std::string time = get_time_string();
    pid_t selfid = getpid();
    char buffer[1024];
    va_list arg;
    va_start(arg, format);
    vsnprintf(buffer, sizeof(buffer), format, arg);
    va_end(arg);
    std::string massage = "[" + time + "]" + "[" + levelstr + "]" + "[" + std::to_string(selfid) + "]" + "[" + filename + "]" + "[" + std::to_string(line) + "]" + buffer;
    LockGuard lockguard(mutex); // RAII
    if (is_save)
    {
        // 保存到文件中
        save_file(logname, massage);
    }
    else
    {   //向屏幕中打印
        std::cout << massage;
    }
}

// 定义宏
#define LOG(level, format, ...)                                            \
    do                                                                     \
    {                                                                      \
        Log_inf(__FILE__, __LINE__, g_save, level, format, ##__VA_ARGS__); \
    } while (0)
#define Enablefile()   \
    do                 \
    {                  \
        g_save = true; \
    } while (0)
#define EnableScrean()  \
    do                  \
    {                   \
        g_save = false; \
    } while (0)
